package com.atguigu.jxc.service.impl;

import com.atguigu.jxc.dao.*;
import com.atguigu.jxc.domain.SaleCountVo;
import com.atguigu.jxc.domain.ServiceVO;
import com.atguigu.jxc.entity.*;
import com.atguigu.jxc.service.SaleListService;
import com.atguigu.jxc.util.BigDecimalUtil;
import com.atguigu.jxc.util.DateUtil;
import com.atguigu.jxc.util.StringUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

@Service
public class SaleListServiceImpl implements SaleListService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private SaleListDao saleListDao;
    @Autowired
    private SaleListGoodsDao saleListGoodsDao;
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private PurchaseListDao purchaseListDao;

    //1.2、销售单保存 和 对应销售商品
    @Override
    @Transactional
    public ServiceVO saveSaleListAndGoods(SaleList saleList, String saleListGoodsStr, String saleNumber) {
        User currentUser = userDao.findUserByName((String) SecurityUtils.getSubject().getPrincipal());
        Gson gson = new Gson();
        List<SaleListGoods> saleListGoodsList = gson.fromJson(saleListGoodsStr, new TypeToken<List<SaleListGoods>>() {
        }.getType());
        saleList.setUserId(currentUser.getUserId());
        saleList.setSaleNumber(saleNumber);
        saleListDao.insertSaleList(saleList);
        SaleList newSaleList = saleListDao.getSaleListByNumber(saleNumber);
        Integer saleListId = newSaleList.getSaleListId();

        for (SaleListGoods saleListGoods : saleListGoodsList) {
            saleListGoods.setSaleListId(saleListId);
            saleListGoodsDao.insertSaleListGoods(saleListGoods);
            Goods goods = goodsDao.findByGoodsId(saleListGoods.getGoodsId());
           int num = goods.getInventoryQuantity() - saleListGoods.getGoodsNum();
           if (num >= 0){
               goods.setInventoryQuantity(num);
               goodsDao.updateGoods(goods);
           }else {
               ServiceVO serviceVO = new ServiceVO(100, "库存不足出单失败", null);
               return serviceVO;
           }
        }
        ServiceVO serviceVO = new ServiceVO(100, "请求成功", null);
        return serviceVO;
    }

    //3.1、销售单查询（可查询条件：销售单号、客户、付款状态）
    @Override
    public List<SaleList> getSaleList(String saleNumber, Integer customerId, Integer state, String sTime, String eTime) {
        List<SaleList> list = saleListDao.selectSaleList(saleNumber,customerId,state,sTime,eTime);
        return list;
    }

    //3.2、销售单商品信息
    @Override
    public List<SaleListGoods> getSaleListGoodsList(Integer saleListId) {
        List<SaleListGoods> list = saleListGoodsDao.selectSaleListGoodsList(saleListId);
        return list;
    }
    //3.3、删除销售单
    @Override
    @Transactional
    public ServiceVO deleteSaleListAndGoods(Integer saleListId) {
        saleListGoodsDao.removeSaleListGoods(saleListId);
        saleListDao.removeSaleList(saleListId);

        ServiceVO<ReturnList> serviceVO = new ServiceVO<>(100, "删除成功", null);
        return serviceVO;
    }
    //2.1、支付结算（修改销售单付款状态）
    //将state 改为1（未付 或未退 改为 已付 已退） 实付金额 改为 应付金额
    @Override
    public ServiceVO updateStateSaleList(Integer saleListId) {
        saleListDao.updateSaleList(saleListId);

        ServiceVO<ReturnList> serviceVO = new ServiceVO<>(100, "支付结算成功", null);
        return serviceVO;
    }
    //4.1、销售统计（可根据 商品类别、商品编码或名称 条件查询）
    @Override
    public String countSaleListGoods(String sTime, String eTime, Integer goodsTypeId, String codeOrName) {
        List<SaleCountVo> list = saleListDao.countSaleListGoods(sTime,eTime,goodsTypeId,codeOrName);
        Gson gson = new Gson();
        String json = gson.toJson(list);
        return json;
    }
    //5.1、按日统计接口
    @SneakyThrows
    @Override
    public String getSaleDataByDay(String sTime, String eTime) {
        List<SaleData> saleDataList = saleListDao.selectSaleDataByDay(sTime,eTime);
        //利用DateUtil工具类 过得时间区间的集合
        List<String> dayList = DateUtil.getTimeSlotByDay(sTime, eTime);
        ArrayList<Map<String, Object>> mapArrayList = new ArrayList<>();
        for (String day : dayList) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("date", day);
            double saleTotal = 0;
            double purchasingTotal = 0;
            double profit = 0;

            for (SaleData saleData : saleDataList) {
                if (saleData.getDate().equals(day)) {
                    saleTotal = saleData.getSaleTotal();
                    purchasingTotal = saleData.getPurchasingTotal();
                    profit = saleTotal - purchasingTotal;
                }
            }
            map.put("profit",BigDecimalUtil.keepTwoDecimalPlaces(profit));
            map.put("saleTotal",BigDecimalUtil.keepTwoDecimalPlaces(saleTotal));
            map.put("purchasingTotal",BigDecimalUtil.keepTwoDecimalPlaces(purchasingTotal));
            mapArrayList.add(map);
        }
            Gson gson = new Gson();
            String json = gson.toJson(mapArrayList);
            return json;

    }
    //5.1、按日统计接口
//    @SneakyThrows
//    @Override
//    public String getSaleDataByDay(String sTime, String eTime) {
//        //按日 以date分组 用sum求和 输出位map
//        List<Map<String, Object>> saleMapList = saleListDao.selectSaleDataByDay(sTime,eTime);
//        List<Map<String, Object>> purchaseMapList = purchaseListDao.selectPurchaseDataByDay(sTime,eTime);
//        //利用DateUtil工具类 过得时间区间的集合
//        List<String> dayList = DateUtil.getTimeSlotByDay(sTime, eTime);
//        ArrayList<Map<String, Object>> mapArrayList = new ArrayList<>();
//        for (String day : dayList) {        //遍历时间集合
//            HashMap<String, Object> map = new HashMap<>();
//            map.put("date", day);
//            double saleTotal = 0;
//            double purchasingTotal = 0;
//            for (Map<String, Object> saleMap : saleMapList) {
//                if (saleMap.get("date").equals(day)) {
//                    //如果日期与day的date相同  将saleTotal赋值  没有相同date 则saleTotal仍未0
//                    saleTotal = Double.parseDouble(saleMap.get("saleTotal").toString());
//                }
//            }
//            for (Map<String, Object> purchaseMap : purchaseMapList) {
//                if (purchaseMap.get("date").equals(day)) {
//                    //如果日期与day的date相同  将purchasingTotal赋值  没有相同date 则purchasingTotal仍未0
//                    purchasingTotal = Double.parseDouble(purchaseMap.get("purchasingTotal").toString());
//                }
//            }
//                double profit = saleTotal - purchasingTotal;
//                map.put("profit", profit);
//                map.put("saleTotal", saleTotal);
//                map.put("purchasingTotal", purchasingTotal);
//                mapArrayList.add(map);
//            }
//            Gson gson = new Gson();
//            String json = gson.toJson(mapArrayList);
//            return json;
//
//    }
    //6.1、按月统计接口
    @SneakyThrows
    @Override
    public String getSaleDataByMonth(String sTime, String eTime) {

        List<SaleData> saleDataList = saleListDao.selectSaleDataByMonth(sTime,eTime);

        //DateUtil工具类方法 获取月为单位的 时间区间
        List<String> timeSlotByMonthList = DateUtil.getTimeSlotByMonth(sTime, eTime);
        ArrayList<Map<String, Object>> mapArrayList = new ArrayList<>();
        //遍历 月份集合
        for (String Month : timeSlotByMonthList) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("date",Month);
            double saleTotal = 0;
            double purchasingTotal = 0;
            double profit = 0;
            for (SaleData saleData : saleDataList) {
                if (saleData.getDate().equals(Month)){
                    saleTotal = saleData.getSaleTotal();
                    purchasingTotal = saleData.getPurchasingTotal();
                    profit = saleTotal - purchasingTotal;
                }
            }

            //将相加后的 数据 放进map中
            map.put("profit",BigDecimalUtil.keepTwoDecimalPlaces(profit));
            map.put("saleTotal",BigDecimalUtil.keepTwoDecimalPlaces(saleTotal));
            map.put("purchasingTotal",BigDecimalUtil.keepTwoDecimalPlaces(purchasingTotal));
            mapArrayList.add(map);
        }
        Gson gson = new Gson();
        String json = gson.toJson(mapArrayList);
        return json;
    }
}
